package com.amos.stuff.leetcode.plusoftwonumbers;

import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Copyright © 2018 五月工作室. All rights reserved.
 *
 * @Package com.amos.stuff.leetcode.plusoftwonumbers
 * @ClassName PlusOfTwoNumbers
 * @Description 两数相加
 * **************************************************************
 * 题目描述：
 * 给出两个 非空 的链表用来表示两个非负的整数。其中，它们各自的位数是按照 逆序 的方式存储的，并且它们的每个节点只能存储 一位 数字。
 * <p/>
 * 如果，我们将这两个数相加起来，则会返回一个新的链表来表示它们的和。
 * <p/>
 * <p>
 * <p/>
 * 备注要求：
 * 您可以假设除了数字 0 之外，这两个数都不会以 0 开头。
 * <p/>
 * 示例说明：
 * 输入：(2 -> 4 -> 3) + (5 -> 6 -> 4)
 * 输出：7 -> 0 -> 8
 * 原因：342 + 465 = 807
 * <p/>
 * 分析：
 * 将数字逆序，然后从第一个下标位相加，如果加值大于10 则进位数标识位为1
 * 再依次计算下一个标位，如果其中一个链表的标志位为空，则置为0
 * 计算到最后一个进位数时，如果进位数不为0，则在链表结尾添加1
 * <p/>
 * 注意的问题:
 * 1. 两个链表长短不一
 * 2. 一个链表为空
 * 3. 求和运算可能出现进位
 * <p/>
 * ***************************************************************
 * @Author Amos
 * @Modifier
 * @Date 2019/10/27 22:54
 * @Version 1.0
 **/
public class PlusOfTwoNumbers {
    /**
     * 计算两个链表的和
     *
     * @param list1 链表1
     * @param list2 链表2
     * @return
     */
    public static List<Integer> plusOfTwoNumbers(List<Integer> list1, List<Integer> list2) {
        if (CollectionUtils.isEmpty(list1)) {
            return list2;
        }
        if (CollectionUtils.isEmpty(list2)) {
            return list1;
        }
        // 获取两个链表的最长的
        int len = list1.size() > list2.size() ? list1.size() : list2.size();
        // 定义目标数组
        List<Integer> destList = new ArrayList<>();
        int carry = 0;
        for (int i = 0; i < len; i++) {
            // 当前下标的list1的值
            // 如果为空的话，则默认是0
            int x = list1.get(i) == null ? 0 : list1.get(i);
            int y = list2.get(i) == null ? 0 : list2.get(i);
            // 添加进位数的同一下标对应的值
            int sum = x + y + carry;
            // 计算进位数的值
            // 留待下一各标记位的计算
            carry = sum / 10;
            // 下标数之和与10取模
            destList.add(sum % 10);
        }
        // 如果循环结束后，进位数不为0 说明两数之和有进位，需要额外添加一个进位数
        if (carry != 0) {
            destList.add(carry);
        }
        return destList;
    }

    public static void main(String[] args) {
        List list1 = CollectionUtils.arrayToList(new Integer[]{2, 3, 4});
        List list2 = CollectionUtils.arrayToList(new Integer[]{5, 7, 9});
        List<Integer> list = plusOfTwoNumbers(list1, list2);
        list.forEach(item -> System.out.print(item + " "));
    }

}
